package org.lifl.compozer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class ComponentMachine {
	protected Container root;
	protected Map<Container, Collection<Component>> composition;
	protected Map<Component, Container> parent;
	protected Collection<ConnectorLink<?>> connexions;

	public ComponentMachine() {
		this.composition = new HashMap<Container, Collection<Component>>();
		this.parent = new HashMap<Component, Container>();
		this.connexions = new ArrayList<ConnectorLink<?>>();
		
		try {
			this.root = new Container(this);
		} catch (NotSameComponentMachineException e) {
			// N'arrive jamais
			e.printStackTrace();
		}
		this.composition.put(root, new ArrayList<Component>());
	}
	
	public void addComponentIntoContainer(Container container, Component comp) 
			throws NotSameComponentMachineException,
			MultipleCompositionException {
		// Consistance niveau machine
		if ((container.getMachine() != this) 
				|| (comp.getMachine() != this)) throw new NotSameComponentMachineException();
		
		// Consistance container
		if (this.parent.get(comp) != null) throw new MultipleCompositionException();
		
		this.composition.get(container).add(comp);
		this.parent.put(comp, container);
	}
	
	public void addRootComponent(Component c) 
			throws NotSameComponentMachineException,
			MultipleCompositionException {
		this.addComponentIntoContainer(root, c);
	}
	
	public void attach(Container c) throws NotSameComponentMachineException {
		if (c.machine != this) throw new NotSameComponentMachineException();
		if ( ! this.composition.containsKey(c)) this.composition.put(c, new ArrayList<Component>());
	}
}
